package com.hy.app.pic;

import android.content.Context;
import android.opengl.GLES30;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;

import com.hy.app.R;
import com.hy.app.utils.OpenGlUtils;
import com.hy.app.utils.TextureUtils;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

/**
 * 图片渲染
 */
public class TextureRenderer implements GLSurfaceView.Renderer {
    private static final String TAG = "TextureRenderer";

    private final FloatBuffer vertexBuffer, textureVertexBuffer;

    private final ShortBuffer vertexIndexBuffer;

    private int programId;

    private int textureId;

    private final String vertexShader;

    private final String fragmentShader;

    private final Context mContext;

    //正交矩阵，避免绘制的bitmap因为拉伸而变形
    private int uMatrixLocation;

    private final float[] mMatrix = new float[16];

    /**
     * 顶点坐标
     * (x,y,z)
     */
    private static final float[] POSITION_VERTEX = {
            0f, 0f, 0f,     //顶点坐标V0
            1f, 1f, 0f,     //顶点坐标V1
            -1f, 1f, 0f,    //顶点坐标V2
            -1f, -1f, 0f,   //顶点坐标V3
            1f, -1f, 0f     //顶点坐标V4
    };

    /**
     * 纹理坐标
     * (s,t)
     */
    private static final float[] TEX_VERTEX = {
            0.5f, 0.5f, //纹理坐标V0
            1f, 0f,     //纹理坐标V1
            0f, 0f,     //纹理坐标V2
            0f, 1.0f,   //纹理坐标V3
            1f, 1.0f    //纹理坐标V4
    };

    /**
     * 索引
     */
    private static final short[] VERTEX_INDEX = {
            0, 1, 2,  //V0,V1,V2 三个顶点组成一个三角形
            0, 2, 3,  //V0,V2,V3 三个顶点组成一个三角形
            0, 3, 4,  //V0,V3,V4 三个顶点组成一个三角形
            0, 4, 1   //V0,V4,V1 三个顶点组成一个三角形
    };

    public TextureRenderer(Context context) {
        mContext = context;

        vertexBuffer = ByteBuffer.allocateDirect(POSITION_VERTEX.length * 4)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();
        vertexBuffer.put(POSITION_VERTEX);
        vertexBuffer.position(0);

        textureVertexBuffer = ByteBuffer.allocateDirect(TEX_VERTEX.length * 4)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();
        textureVertexBuffer.put(TEX_VERTEX);
        textureVertexBuffer.position(0);

        vertexIndexBuffer = ByteBuffer.allocateDirect(VERTEX_INDEX.length * 2)
                .order(ByteOrder.nativeOrder())
                .asShortBuffer();
        vertexIndexBuffer.put(VERTEX_INDEX);
        vertexIndexBuffer.position(0);

        vertexShader = OpenGlUtils.readRawShaderFile(mContext, R.raw.texture_vertex_shader);
        fragmentShader = OpenGlUtils.readRawShaderFile(mContext, R.raw.texture_fragment_shader);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES30.glClearColor(0.5f, 0.5f, 0.5f, 0.5f);

        int vertexShaderId = OpenGlUtils.compileVertexShader(vertexShader);
        int fragmentShaderId = OpenGlUtils.compileFragmentShader(fragmentShader);
        programId = OpenGlUtils.linkProgram(vertexShaderId, fragmentShaderId);

        //获取自适应属性
        uMatrixLocation = GLES30.glGetUniformLocation(programId, "u_Matrix");

        //加载纹理
        textureId = TextureUtils.loadTexture(mContext, R.mipmap.main);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        GLES30.glViewport(0, 0, width, height);

        float aspectRatio = width > height ? (float) width / height : (float) height / width;
        if (width > height) {
            //横屏
            Matrix.orthoM(mMatrix, 0, -aspectRatio, aspectRatio, -1f, 1f, -1f, 1f);
        } else {
            //竖屏
            Matrix.orthoM(mMatrix, 0, -1f, 1f, -aspectRatio, aspectRatio, -1f, 1f);
        }
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);

        //正交投影矩阵
        GLES30.glUniformMatrix4fv(uMatrixLocation, 1, false, mMatrix, 0);

        //使用程序片段
        GLES30.glUseProgram(programId);

        //启用顶点坐标属性
        GLES30.glEnableVertexAttribArray(0);
        GLES30.glVertexAttribPointer(0, 3, GLES30.GL_FLOAT, false, 0, vertexBuffer);

        //启用纹理坐标属性
        GLES30.glEnableVertexAttribArray(1);
        GLES30.glVertexAttribPointer(1, 2, GLES30.GL_FLOAT, false, 0, textureVertexBuffer);

        //激活纹理
        GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
        //绑定纹理
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textureId);

        //绘制
        GLES30.glDrawElements(GLES30.GL_TRIANGLES, VERTEX_INDEX.length, GLES30.GL_UNSIGNED_SHORT, vertexIndexBuffer);
    }
}
